# Lasty is ment to replace user-is-listening for the song that 'user' is listening
# getting that information from the last.fm rss
# last-robot@appspot.com
# author: Marti Planellas (beldar.cat@gmail.com)
# in Wave: beldar@wavesandbox.com

__author__ = 'beldar.cat@gmail.com (Marti Planellas)'

from waveapi import events
from waveapi import model
from waveapi import robot
from waveapi import document
from xml.dom import minidom
from waveapi.document import Range
import urllib
import logging
import re

logger = logging.getLogger('Lasty')
logger.setLevel(logging.DEBUG)

def GetSong(user):
	song = 1
	xml = minidom.parse(urllib.urlopen('http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user='+user+'&api_key=b25b959554ed76058ac220b7b2e0a026'))
	artist='Artist not available'
	songtitle='Song not available'
	album='Album not available'
	songlink='#'
	albumart='http://last-robot.appspot.com/assets/lasty.png'
	spotyurl='#'
	try:
		track = xml.getElementsByTagName('track')[0]
	except Exception:
		song = 0
	#if song != 0:
	try:
		artist = track.childNodes[1].firstChild.data
	except Exception:
		song = 0
	try:
		songtitle = track.childNodes[3].firstChild.data
	except Exception:
		song = 0
	try:
		album = track.childNodes[9].firstChild.data
	except Exception:
		song = 0
	try:
		songlink = track.childNodes[11].firstChild.data
	except Exception:
		song = 0
	try:
		albumart = track.childNodes[17].firstChild.data
	except Exception:
		song = 0
	intro = '\n'+user+' is listening to: \n'
	query = songtitle+' '+artist
	query = query.replace(" ", "+")
	xmlsp = minidom.parse(urllib.urlopen('http://ws.spotify.com/search/1/track?q='+query))
	try:
		tr = xmlsp.getElementsByTagName('track')[0]
		spoty = tr.attributes['href'].value
		spoty = spoty.split(":")
		#0 spotify, #1 track, #2 ID
		spotyurl = 'http://open.spotify.com/track/'+spoty[2]
		logger.debug('Href spotyurl: '+spotyurl)
	except Exception:
		song = 0
	song = [intro,artist,songtitle, album, songlink, albumart, spotyurl]
	return song
	
def OnBlipSubmit(properties, context):
  oblip = context.GetBlipById(properties['blipId'])
  text = oblip.GetDocument().GetText()
  #text = doc.GetText()
  newtext = text
  #pat = re.findall('(*)|imlistening')
  p = re.compile(r'(\w+)-is-listening')
  users = p.findall(text)
  startpos = 0
  for user in users:
   song = GetSong(user)
   logger.debug('arribo aqui')
   logger.debug(song)
   if song == 0:
	m = re.search(user+'-is-listening', newtext)
	newtext = newtext.replace(user+'-is-listening', 'The user '+user+' doesn\'t exists or doesn\'t have recent tracks!')
	oblip.GetDocument().SetText(newtext)
	oblip.GetDocument().SetAnnotation(Range(m.start(), m.start()+56+len(user)), "style/fontWeight", "bold")
   else:
	#0: intro #1: artist, #2: song, #3:album, #4: songlink, #5: albumart, #6: spotyurl
	#newtext = newtext.replace(user+'-is-listening', '')
	oblip.GetDocument().SetText(newtext)
	blip = oblip.GetDocument().AppendInlineBlip()
	#blip = context.GetRootWavelet().CreateBlip()
	doc = blip.GetDocument()
	frase = '\n'+song[2]+'\n'+song[1]+'\n'+song[3]+'\nYou can hear it here\nOpen in Spotify! (new)\n'
	doc.AppendText(song[0])
	image = document.Image(song[5])
	doc.AppendElement(image)
	doc.AppendText(frase)
	if song != 0:
		startpos = 0
		stuff = blip.GetDocument()
    	stuff.SetAnnotation(Range(startpos,20+len(user)), "style/fontWeight", "bold")
    	startpos += 23+len(user)
    	logger.debug(song[2])
    	logger.debug(song[3])
    	stuff.SetAnnotation(Range(startpos,startpos+len(song[2])), "style/fontSize", "22pt")
    	startpos += len(song[2])
    	stuff.SetAnnotation(Range(startpos,startpos+1+len(song[1])), "style/fontSize", "18pt")
    	startpos += len(song[1])+1
    	stuff.SetAnnotation(Range(startpos,startpos+2+len(song[3])), "style/fontSize", "16pt")
    	startpos += len(song[3])+2
    	stuff.SetAnnotation(Range(startpos,startpos+21), "link/manual", song[4])
    	startpos += 21
    	logger.debug('song[6]: '+song[6])
    	stuff.SetAnnotation(Range(startpos,startpos+16), "link/manual", song[6])   	
    	startpos += 16

def OnParticipantsChanged(properties, context):
  """Invoked when any participants have been added/removed."""
  added = properties['participantsAdded']
  for p in added:
    Notify(context,p)

def OnRobotAdded(properties, context):
  """Invoked when the robot has been added."""
  root_wavelet = context.GetRootWavelet()
  root_wavelet.CreateBlip().GetDocument().SetText("Hi I'm Lasty, if you have a Last.fm account you can type 'YourLastFMUser-is-listening' and I will tell you what song are you listening! Example Beldar-is-listening")
  logger.debug('Robot Added')

def Notify(context,p):
  if p != 'last-robot@appspot.com':
   root_wavelet = context.GetRootWavelet()
   logger.debug(p+' joined')
   #root_wavelet.CreateBlip().GetDocument().SetText("Hi "+p+" type 'YourLastFMUser-is-listening' and I will tell you what song are you listening!")

if __name__ == '__main__':
  facey = robot.Robot('Lasty', 
      version='3',
	  image_url='http://last-robot.appspot.com/assets/lasty.png',
      profile_url='http://last-robot.appspot.com/')
  facey.RegisterHandler(events.WAVELET_PARTICIPANTS_CHANGED, OnParticipantsChanged)
  facey.RegisterHandler(events.WAVELET_SELF_ADDED, OnRobotAdded)
  facey.RegisterHandler(events.BLIP_SUBMITTED, OnBlipSubmit)
  facey.Run(debug=True)